package com.lnlyj.imagtext;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.style.ImageSpan;

import java.lang.ref.WeakReference;

import androidx.annotation.NonNull;

/**
 * wanglei 2020-02-22 10:35
 */
public class CustomImageSpan extends ImageSpan {

    private static final String TAG = "CustomImageSpan";

    private int fontHeight = 1;
    private float lineSpacingExtra = 0;
    private int lineCount;
    private int lineHeight;

    public CustomImageSpan(@NonNull Bitmap b) {
        super(b);
    }

    public CustomImageSpan(@NonNull Bitmap b, int verticalAlignment) {
        super(b, verticalAlignment);
    }

    public CustomImageSpan(@NonNull Context context, @NonNull Bitmap b) {
        super(context, b);
    }

    public CustomImageSpan(@NonNull Context context, @NonNull Bitmap b, int verticalAlignment) {
        super(context, b, verticalAlignment);
    }

    public CustomImageSpan(@NonNull Drawable d) {
        super(d);
    }

    public CustomImageSpan(@NonNull Drawable d, int verticalAlignment) {
        super(d, verticalAlignment);
    }

    public CustomImageSpan(@NonNull Drawable d, @NonNull String source) {
        super(d, source);
    }

    public CustomImageSpan(@NonNull Drawable d, @NonNull String source, int verticalAlignment) {
        super(d, source, verticalAlignment);
    }

    public CustomImageSpan(@NonNull Context context, @NonNull Uri uri) {
        super(context, uri);
    }

    public CustomImageSpan(@NonNull Context context, @NonNull Uri uri, int verticalAlignment) {
        super(context, uri, verticalAlignment);
    }

    public CustomImageSpan(@NonNull Context context, int resourceId) {
        super(context, resourceId);
    }

    public CustomImageSpan(@NonNull Context context, int resourceId, int verticalAlignment) {
        super(context, resourceId, verticalAlignment);
    }

    @Override
    public Drawable getDrawable() {

        Drawable drawable = super.getDrawable();

        int width = drawable.getBounds().right;
        int height = drawable.getBounds().bottom;

        if (height != fontHeight) {
            width = width / height * fontHeight;
            height = fontHeight;
        }

        drawable.setBounds(0,0, width, height);

        return drawable;
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end,
                       Paint.FontMetricsInt fontMetricsInt) {
        Drawable drawable = getCachedDrawable();
        Rect rect = drawable.getBounds();
        if (fontMetricsInt != null) {
            Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

            int fontHeight = fmPaint.bottom - fmPaint.top;
            int drHeight = rect.bottom - rect.top;

            int top = drHeight / 2 - fontHeight / 4;
            int bottom = drHeight / 2 + fontHeight / 4;

            fontMetricsInt.ascent = -bottom;
            fontMetricsInt.top = -bottom;
            fontMetricsInt.bottom = top;
            fontMetricsInt.descent = top;
        }
        return rect.right;
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end,
                     float x, int top, int y, int bottom, Paint paint) {
        Drawable drawable = getCachedDrawable();
        canvas.save();

        int lineSpacingExtraHeight = (int) (lineSpacingExtra / 2);

        if (bottom > (lineHeight * (lineCount - 1) + lineSpacingExtra)) {
            lineSpacingExtraHeight = 0;
        }

        int transY = ((bottom - top) - drawable.getBounds().bottom) / 2 + top - 2 - lineSpacingExtraHeight;
        canvas.translate(x, transY);
        drawable.draw(canvas);
        canvas.restore();
    }

    private Drawable getCachedDrawable() {
        WeakReference<Drawable> wr = mDrawableRef;
        Drawable d = null;

        if (wr != null)
            d = wr.get();

        if (d == null) {
            d = getDrawable();
            mDrawableRef = new WeakReference<Drawable>(d);
        }

        return d;
    }

    private WeakReference<Drawable> mDrawableRef;

    public void setFontHeight(int fontHeight) {
        this.fontHeight = fontHeight;
    }

    public void setLineSpacingExtra(float lineSpacingExtra) {
        this.lineSpacingExtra = lineSpacingExtra;
    }

    public void setLineCount(int lineCount) {
        this.lineCount = lineCount;
    }

    public void setLineHeight(int lineHeight) {
        this.lineHeight = lineHeight;
    }
}
